import type {
  ElTableColumn as ETC,
  TableInstance,
  TableProps,
} from "element-plus";
import type { listCurrentPageKey, listPageSizeKey } from "@/config";
import type { ExtractPropTypes } from "vue";

export type TableApiParams<
  /** 静态参数 */
  SQ extends Record<string, any> = Record<string, any>,
> = SQ & {
  /** 当前页数 */
  [listCurrentPageKey]: number;
  /** 每页条数 */
  [listPageSizeKey]: number;
};

export interface TableApiResult<
  T extends Record<string, any> = Record<string, any>,
> {
  /** 总数 */
  total: number;
  list: T[];
}

export interface TableMainInstance {
  refresh: (silent?: boolean) => void;
  reload: (slice?: boolean) => void;
  getTableInstance: () => TableInstance | undefined;
}

/** 表格列默认作用域 */
export interface TableColumnDefaultScope<
  T extends Record<string, any>,
  F extends Record<string, any>,
> {
  row: T;
  column: ElTableColumnProps<T, F>;
  $index: number;
  injectInfo: F;
  exposeInfo: TableMainInstance;
}

/** 表格列组件props[$开头的属性vue报错] */
export type TableColumnComponentProps<
  T extends Record<string, any>,
  F extends Record<string, any>,
> = Omit<TableColumnDefaultScope<T, F>, "$index"> & {
  _index: TableColumnDefaultScope<T, F>["$index"];
};

/** 表格列header作用域 */
export interface TableColumnHeaderScope<
  T extends Record<string, any>,
  F extends Record<string, any>,
> {
  column: ElTableColumnProps<T, F>;
  $index: number;
  injectInfo: F;
  exposeInfo: TableMainInstance;
}

export type ExtractElTableColumnProps = ExtractPropTypes<typeof ETC>;

export type ElTableColumnProps<
  T extends Record<string, any> = Record<string, any>,
  /** 期望注入到表格列插槽上的额外内容 */
  F extends Record<string, any> = {},
> = Omit<ExtractPropTypes<typeof ETC>, "prop" | "columnKey" | "type"> &
  Partial<{
    prop: Extract<keyof T, string> | `${Uppercase<string>}`;
    columnKey: ElTableColumnProps<T>["prop"];
    type: "default" | "selection" | "index" | "expand";
    fixed: "left" | "right" | boolean;
    align: "left" | "center" | "right";
    headerAlign: "left" | "center" | "right";
    filterPlacement:
      | "top"
      | "top-start"
      | "top-end"
      | "bottom"
      | "bottom-start"
      | "bottom-end"
      | "left"
      | "left-start"
      | "left-end"
      | "right"
      | "right-start"
      | "right-end";

    /** 插槽render */
    render:
      | string
      | Record<string, any>
      | ((props: TableColumnComponentProps<T, F>) => VNode);

    /** 表头插槽render */
    headerRender:
      | string
      | Record<string, any>
      | ((props: TableColumnHeaderScope<T, F>) => VNode);
  }>;

export interface TableMainProps<
  /** 行数据结构 */
  T extends Record<string, any>,
  /** 静态参数 */
  SQ extends Record<string, any>,
  /** 期望注入到表格列插槽上的额外内容 */
  F extends Record<string, any>,
> {
  /** 展示分页器 */
  showPager?: boolean;
  /** 参数 */
  query?: SQ;
  /** 每页条数 */
  pageSizeInit?: number;
  pageSizeOptions?: number[];
  pageLayout?: string;
  rowKey: Extract<keyof T, string> | ((row: T) => string);
  /** 请求api */
  api: (params: TableApiParams<SQ>) => Promise<TableApiResult<T>>;
  tableProps?: Omit<TableProps<T>, "data" | "maxHeight" | "rowKey"> &
    Record<`on${Capitalize<string>}`, (...args: any[]) => any>;
  columns: ElTableColumnProps<T, F>[];
  /** 最大高度 */
  maxHeight?: number;
  /** 表头背景色 */
  headerColor?: string;
  /** 精细化布局 */
  refine?: boolean;
  /** 精细化预留高度 */
  refineReduceHeight?: number;
  /** 给插槽注入的方法 */
  injectInfo?: F;
}
